<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test antdesign</title>
    <!-- 引入 Ant Design CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/antd@4.24.15/dist/antd.min.css">
    <style>
        .container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .upload-area {
            border: 2px dashed #d9d9d9;
            border-radius: 6px;
            padding: 20px;
            text-align: center;
            margin: 20px 0;
            cursor: pointer;
        }
        .upload-area:hover {
            border-color: #40a9ff;
        }
        .raw-data {
            white-space: pre-wrap;
            word-wrap: break-word;
            max-height: 500px;
            overflow-y: auto;
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 4px;
            font-family: monospace;
            font-size: 12px;
            margin-top: 20px;
        }
        .task-status {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div id="root"></div>

    <!-- 引入 React 和 ReactDOM -->
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- 引入 Ant Design -->
    <script crossorigin src="https://cdn.jsdelivr.net/npm/antd@4.24.15/dist/antd.min.js"></script>
    <!-- 引入 Babel Standalone 用于 JSX 转换 -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    
    <script type="text/babel">
        const { Button, Card, Spin, Alert, Upload } = antd;
        const { Dragger } = Upload;
        
        class App extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
                    file: null,
                    loading: false,
                    task_id: null,
                    task_status: null,
                    raw_data: null,
                    error: null
                };
            }
            
            handleFileChange = (event) => {
                const file = event.target.files[0];
                if (file) {
                    this.setState({ file });
                }
            }
            
            handleDragOver = (event) => {
                event.preventDefault();
            }
            
            handleDrop = (event) => {
                event.preventDefault();
                const file = event.dataTransfer.files[0];
                if (file) {
                    this.setState({ file });
                }
            }
            
            handleFormDataUpload = async () => {
                if (!this.state.file) {
                    antd.message.error('请先选择文件');
                    return;
                }
                
                this.setState({ loading: true, task_id: null, task_status: null, raw_data: null, error: null });
                
                const formData = new FormData();
                formData.append('resume', this.state.file);
                
                try {
                    const response = await fetch('http://127.0.0.1:5000/api/v1/predict_from_resume_async', {
                        method: 'POST',
                        body: formData
                    });
                    
                    const data = await response.json();
                    this.setState({ raw_data: JSON.stringify(data, null, 2) });
                    
                    if (response.status === 202) {
                        const taskId = data.data.task_id;
                        this.setState({ task_id: taskId, task_status: 'processing' });
                        this.pollTaskStatus(taskId);
                    } else {
                        this.setState({ loading: false, error: data.message });
                    }
                } catch (error) {
                    this.setState({ loading: false, error: error.message });
                }
            }

            handleBase64Upload = async () => {
                if (!this.state.file) {
                    antd.message.error('请先选择文件');
                    return;
                }
                
                this.setState({ loading: true, task_id: null, task_status: null, raw_data: null, error: null });
                
                try {
                    const reader = new FileReader();
                    reader.onload = async (e) => {
                        try {
                            const base64Content = e.target.result.split(',')[1];
                            
                            const requestData = {
                                resume_base64: base64Content,
                                filename: this.state.file.name
                            };
                            
                            const response = await fetch('http://127.0.0.1:5000/api/v1/predict_from_resume_async', {
                                method: 'POST',
                                headers: {
                                    'Content-Type': 'application/json'
                                },
                                body: JSON.stringify(requestData)
                            });
                            
                            const data = await response.json();
                            this.setState({ raw_data: JSON.stringify(data, null, 2) });
                            
                            if (response.status === 202) {
                                const taskId = data.data.task_id;
                                this.setState({ task_id: taskId, task_status: 'processing' });
                                this.pollTaskStatus(taskId);
                            } else {
                                this.setState({ loading: false, error: data.message });
                            }
                        } catch (error) {
                            this.setState({ loading: false, error: error.message });
                        }
                    };
                    reader.onerror = (error) => {
                        this.setState({ loading: false, error: "文件读取失败: " + error.message });
                    };
                    reader.readAsDataURL(this.state.file);
                } catch (error) {
                    this.setState({ loading: false, error: error.message });
                }
            }
            
            handleFormDataUploadSync = async () => {
                if (!this.state.file) {
                    antd.message.error('请先选择文件');
                    return;
                }
                
                this.setState({ loading: true, task_id: null, task_status: null, raw_data: null, error: null });
                
                const formData = new FormData();
                formData.append('resume', this.state.file);
                
                try {
                    const response = await fetch('http://127.0.0.1:5000/api/v1/predict_from_resume', {
                        method: 'POST',
                        body: formData
                    });
                    
                    const data = await response.json();
                    this.setState({ raw_data: JSON.stringify(data, null, 2) });
                    
                    if (response.status === 200) {
                        this.setState({ loading: false });
                    } else {
                        this.setState({ loading: false, error: data.message });
                    }
                } catch (error) {
                    this.setState({ loading: false, error: error.message });
                }
            }

            handleBase64UploadSync = async () => {
                if (!this.state.file) {
                    antd.message.error('请先选择文件');
                    return;
                }
                
                this.setState({ loading: true, task_id: null, task_status: null, raw_data: null, error: null });
                
                try {
                    const reader = new FileReader();
                    reader.onload = async (e) => {
                        try {
                            const base64Content = e.target.result.split(',')[1];
                            
                            const requestData = {
                                resume_base64: base64Content,
                                filename: this.state.file.name
                            };
                            
                            const response = await fetch('http://127.0.0.1:5000/api/v1/predict_from_resume', {
                                method: 'POST',
                                headers: {
                                    'Content-Type': 'application/json'
                                },
                                body: JSON.stringify(requestData)
                            });
                            
                            const data = await response.json();
                            this.setState({ raw_data: JSON.stringify(data, null, 2) });
                            
                            if (response.status === 200) {
                                this.setState({ loading: false });
                            } else {
                                this.setState({ loading: false, error: data.message });
                            }
                        } catch (error) {
                            this.setState({ loading: false, error: error.message });
                        }
                    };
                    reader.onerror = (error) => {
                        this.setState({ loading: false, error: "文件读取失败: " + error.message });
                    };
                    reader.readAsDataURL(this.state.file);
                } catch (error) {
                    this.setState({ loading: false, error: error.message });
                }
            }
            
            pollTaskStatus = async (taskId) => {
                const pollInterval = setInterval(async () => {
                    try {
                        const response = await fetch(`http://127.0.0.1:5000/api/v1/predict_from_resume_status/${taskId}`);
                        const data = await response.json();
                        this.setState({ raw_data: JSON.stringify(data, null, 2) });
                        
                        this.setState({ task_status: data.data.status });
                        
                        if (data.data.status === 'completed') {
                            clearInterval(pollInterval);
                            this.setState({ loading: false });
                        } else if (data.data.status === 'failed') {
                            clearInterval(pollInterval);
                            this.setState({ loading: false, error: data.data.error });
                        }
                    } catch (error) {
                        clearInterval(pollInterval);
                        this.setState({ loading: false, error: "轮询任务状态失败: " + error.message });
                    }
                }, 2000);
            }
            
            renderTaskStatus = () => {
                const { task_id, task_status } = this.state;
                
                if (!task_id) return null;
                
                return (
                    <Card title="异步任务状态" className="task-status">
                        <p><strong>任务ID:</strong> {task_id}</p>
                        <p><strong>状态:</strong> 
                            {task_status === 'processing' && <span style={{color: 'orange'}}> 处理中</span>}
                            {task_status === 'completed' && <span style={{color: 'green'}}> 完成</span>}
                            {task_status === 'failed' && <span style={{color: 'red'}}> 失败</span>}
                        </p>
                        {task_status === 'processing' && (
                            <div>
                                <Spin />
                                <p>正在处理中，请稍候...</p>
                            </div>
                        )}
                    </Card>
                );
            }
            
            renderRawData = () => {
                const { raw_data } = this.state;
                
                if (!raw_data) return null;
                
                // 解析JSON数据
                let parsedData = null;
                try {
                    parsedData = JSON.parse(raw_data);
                } catch (e) {
                    console.error("JSON解析失败:", e);
                }
                
                return (
                    <div>
                        {parsedData && parsedData.data && this.renderCommentSection(parsedData.data)}
                        <Card title="API原始响应数据">
                            <pre className="raw-data">
                                {raw_data}
                            </pre>
                        </Card>
                    </div>
                );
            }
            
            renderCommentSection = (data) => {
                const comment = data.comment;
                if (!comment) return null;
                
                return (
                    <Card title="用户评价" style={{ marginBottom: 20 }}>
                        <div style={{ marginBottom: 15 }}>
                            <h3 style={{ color: '#1890ff', marginBottom: 8 }}>市场定位分析</h3>
                            <p>{comment.positioning}</p>
                        </div>
                        <div style={{ marginBottom: 15 }}>
                            <h3 style={{ color: '#1890ff', marginBottom: 8 }}>薪资水平预测</h3>
                            <p>{comment.salary}</p>
                        </div>
                        <div style={{ marginBottom: 15 }}>
                            <h3 style={{ color: '#1890ff', marginBottom: 8 }}>能力提升建议</h3>
                            <p>{comment.advice}</p>
                        </div>
                        <div style={{ marginBottom: 15 }}>
                            <h3 style={{ color: '#1890ff', marginBottom: 8 }}>职业发展路径</h3>
                            <p>{comment.growing}</p>
                        </div>
                    </Card>
                );
            }
            
            render() {
                const { file, loading, error } = this.state;
                
                return (
                    <div className="container">
                        
                        <div 
                            className="upload-area" 
                            onDragOver={this.handleDragOver}
                            onDrop={this.handleDrop}
                        >
                            <p>点击选择或拖拽简历文件到此处上传</p>
                            <p>支持 PDF 和 Word 文档格式</p>
                            {file && <p>已选择文件: {file.name}</p>}
                            <input 
                                type="file" 
                                accept=".pdf,.docx" 
                                style={{ display: 'none' }}
                                onChange={this.handleFileChange}
                                ref={(input) => { this.fileInput = input; }}
                            />
                            <Button 
                                type="primary" 
                                onClick={() => this.fileInput && this.fileInput.click()}
                            >
                                选择文件
                            </Button>
                        </div>
                        
                        <div>
                            <Button 
                                type="primary" 
                                onClick={this.handleFormDataUpload}
                                disabled={!file}
                                style={{ marginRight: 10 }}
                                loading={loading}
                            >
                                Form-Data 上传（异步）
                            </Button>
                            <Button 
                                type="primary" 
                                onClick={this.handleBase64Upload}
                                disabled={!file}
                                style={{ marginRight: 10 }}
                                loading={loading}
                            >
                                Base64 上传（异步）
                            </Button>
                            <Button 
                                type="default" 
                                onClick={this.handleFormDataUploadSync}
                                disabled={!file}
                                style={{ marginRight: 10 }}
                                loading={loading}
                            >
                                Form-Data 上传（同步）
                            </Button>
                            <Button 
                                type="default" 
                                onClick={this.handleBase64UploadSync}
                                disabled={!file}
                                loading={loading}
                            >
                                Base64 上传（同步）
                            </Button>
                        </div>
                        
                        {this.renderTaskStatus()}
                        
                        {error && (
                            <Alert 
                                message="错误"
                                description={error}
                                type="error"
                                showIcon
                                style={{ marginTop: 20 }}
                            />
                        )}
                        
                        {this.renderRawData()}
                    </div>
                );
            }
        }
        
        ReactDOM.render(<App />, document.getElementById('root'));
    </script>
</body>
</html>